package cn.hhchat.wp.service;

import cn.hhchat.wp.dto.form.CreateGroupForm;
import cn.hhchat.wp.dto.group.SimpleGroupInfo;
import cn.hhchat.wp.dto.group.SimpleGroupPostInfo;
import cn.hhchat.wp.entity.JoinRelationEntity;
import cn.hhchat.wp.entity.GroupEntity;
import cn.hhchat.wp.entity.SubscribeRelationEntity;
import cn.hhchat.wp.entity.UserEntity;
import cn.hhchat.wp.enums.RoleEnum;
import cn.hhchat.wp.repository.GroupRepository;
import cn.hhchat.wp.repository.JoinRelationRepository;
import cn.hhchat.wp.repository.SubscribeRepository;
import cn.hhchat.wp.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created this one by HMH on 2017/10/22.
 */
@Slf4j
@Service
@Transactional
public class GroupService {

    public List<GroupEntity> getAll() {
        Sort sort = new Sort(new Sort.Order(Sort.Direction.ASC, "isFinished"), new Sort.Order(Sort.Direction.ASC, "id"));
        return groupRepository.findAll(sort);
    }

    public List<GroupEntity> getAllUnFinished() {
        Sort sort = new Sort(new Sort.Order(Sort.Direction.ASC, "isFinished"), new Sort.Order(Sort.Direction.ASC, "id"));
        return groupRepository.findAllByIsFinished(false, sort);
    }

    public GroupEntity save(GroupEntity group) {
        return groupRepository.save(group);
    }

    public GroupEntity finish(GroupEntity groupEntity) {
        groupEntity.setIsFinished(true);
        return save(groupEntity);
    }

    public GroupEntity setPostTemplate(GroupEntity group, String postTemplate) {
        group.setPostTemplate(postTemplate);
        return save(group);
    }

    public void setSubscribe(GroupEntity group, UserEntity user, boolean isSubscribe){
        SubscribeRelationEntity subscribeRelation = subscribeRepository.findByGroupAndUser(group, user);
        if (isSubscribe) {
            if (subscribeRelation == null) {
                subscribeRelation = new SubscribeRelationEntity();
                subscribeRelation.setGroup(group);
                subscribeRelation.setUser(user);
                subscribeRepository.save(subscribeRelation);
            }
        }else{
            if (subscribeRelation == null) {
                return;
            }
            subscribeRepository.delete(subscribeRelation);
        }
    }

    public GroupEntity reStart(GroupEntity groupEntity) {
        groupEntity.setIsFinished(false);
        return save(groupEntity);
    }

    public GroupEntity getById(@RequestBody long id) {
        return groupRepository.findById(id);
    }

    public GroupEntity createGroup(CreateGroupForm form, UserEntity user) {
        GroupEntity groupEntity = new GroupEntity(form);
        groupEntity.setOwner(user);
        groupEntity = save(groupEntity);

//        添加为管理员
        join(groupEntity, user, true);

        return save(groupEntity);
    }

    public List<GroupEntity> getAllUnFinishedByActiveUser(UserEntity user){
        return joinRelationRepository.findByUserAndIsActiveAndGroup_IsFinished(user, true, false).stream().map(JoinRelationEntity::getGroup).collect(Collectors.toList());
    }

    public SimpleGroupInfo toSimpleGroupInfo(GroupEntity group) {
        SimpleGroupInfo simpleGroupInfo = new SimpleGroupInfo();
        simpleGroupInfo.setId(group.getId());
        simpleGroupInfo.setName(group.getName());
        simpleGroupInfo.setState(group.getStatus());
        simpleGroupInfo.setDescription(group.getDescription());
        simpleGroupInfo.setCreateTime(DateUtil.formatDate(group.getCreateTime()));
        simpleGroupInfo.setMemberCount(userService.countGroupMembers(group));
        return simpleGroupInfo;
    }

    public List<JoinRelationEntity> getMembers(GroupEntity group){
        return joinRelationRepository.findByGroupAndIsActive(group, true);
    }

    public SimpleGroupPostInfo toSimpleGroupPostInfoOfThisWeek(GroupEntity group, UserEntity user) {
        Instant start = Instant.now();
        SimpleGroupPostInfo simpleGroupPostInfo = new SimpleGroupPostInfo();
        simpleGroupPostInfo.setId(group.getId());
        simpleGroupPostInfo.setName(group.getName());
        simpleGroupPostInfo.setDescription(group.getDescription());
        simpleGroupPostInfo.setMemberCount(userService.countGroupMembers(group));
        simpleGroupPostInfo.setState(group.getStatus());
        simpleGroupPostInfo.setPostThisWeek(postService.countPostThisWeekByGroup(group));
        simpleGroupPostInfo.setPosterThisWeek(postService.countPosterThisWeekByGroup(group));
        simpleGroupPostInfo.setIsSubscribe(null != subscribeRepository.findByGroupAndUser(group, user));
        return simpleGroupPostInfo;
    }

    public JoinRelationEntity join(GroupEntity group, UserEntity user, boolean isAdmin){
        JoinRelationEntity joinRelation = joinRelationRepository.findByGroupAndUser(group, user);
        joinRelation = joinRelation == null ? new JoinRelationEntity() : joinRelation;
        joinRelation.setIsActive(true);
        joinRelation.setGroup(group);
        joinRelation.setIsAdmin(false);
        joinRelation.setIsAdmin(isAdmin);
        joinRelation.setUser(user);
        return save(joinRelation);
    }

    public JoinRelationEntity save(JoinRelationEntity joinRelation) {
        return joinRelationRepository.save(joinRelation);
    }

    public JoinRelationEntity removeMember(GroupEntity group, UserEntity user) {
        JoinRelationEntity joinRelation = joinRelationRepository.findByGroupAndUser(group, user);
        if (joinRelation == null) {
            //解除关系
            joinRelation.setIsActive(false);
            roleService.setRole(user, RoleEnum.用户);
            setSubscribe(group, user, false);
            return save(joinRelation);
        }
        return null;
    }


    public JoinRelationEntity setAdmin(GroupEntity group, UserEntity user, boolean isAdmin) {
        JoinRelationEntity joinRelation = joinRelationRepository.findByGroupAndUser(group, user);
        joinRelation.setIsAdmin(isAdmin);
        return save(joinRelation);
    }

    public void setNeedSubmit(GroupEntity group, UserEntity user, boolean needSubmit) {
        JoinRelationEntity joinRelation = joinRelationRepository.findByGroupAndUserAndIsActive(group, user, true);
        joinRelation.setNeedSubmit(needSubmit);
        joinRelationRepository.save(joinRelation);
    }

    @Autowired
    GroupRepository groupRepository;

    @Autowired
    RoleService roleService;

    @Autowired
    UserService userService;

    @Autowired
    PostService postService;

    @Autowired
    SubscribeRepository subscribeRepository;

    @Autowired
    JoinRelationRepository joinRelationRepository;

}
